package com.hunttown.common.dao.base;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.hunttown.common.dao.datasource.MasterSlaveDataSource;
import com.hunttown.common.dao.exception.UnknownDataAccessException;
import com.hunttown.common.dao.transaction.TransactionManagers;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.util.Assert;

abstract class AbstractDao implements ApplicationContextAware {
    private static TransactionManagers transactionManagers;
    private boolean isNonMasterSlaveMode = true;
    private SqlMapClient sqlMapClient;
    private DataSource dataSource;

    AbstractDao() {
    }

    public void setSqlMapClient(SqlMapClient sqlMapClient) {
        this.sqlMapClient = sqlMapClient;
        this.dataSource = this.sqlMapClient.getDataSource();
        DataSource ds = this.dataSource;
        if (ds instanceof TransactionAwareDataSourceProxy) {
            ds = ((TransactionAwareDataSourceProxy) ds).getTargetDataSource();
        }

        if (ds instanceof MasterSlaveDataSource) {
            this.isNonMasterSlaveMode = false;
        }

    }

    protected DataSource getDataSource() {
        return this.dataSource;
    }

    protected SqlMapClient getSqlMapClient() {
        return this.sqlMapClient;
    }

    protected boolean isNonMasterSlaveMode() {
        return this.isNonMasterSlaveMode;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (transactionManagers == null) {
            transactionManagers = (TransactionManagers) applicationContext.getBean("transactionManagers", TransactionManagers.class);
            Assert.notNull(transactionManagers, "must define an TransactionManagers type bean, name : transactionManagers");
        }

    }

    protected <T> T executeWithObjectResult(SqlMapClient sqlMapClient, DataSource dataSource, SqlMapClientCallback<T> callback) throws DataAccessException {
        Assert.notNull(dataSource, "None DataSource is specified!");
        Assert.notNull(callback, "None SqlMapClientCallback is specified!");
        Assert.notNull(sqlMapClient, "None SqlMapClient is specified!");
        SqlMapSession session = null;

        Object t;
        try {
            Connection springCon = null;
            boolean isTransactionAware = dataSource instanceof TransactionAwareDataSourceProxy;

            try {
                springCon = isTransactionAware ? dataSource.getConnection() : DataSourceUtils.getConnection(dataSource);
                session = sqlMapClient.openSession(springCon);
            } catch (SQLException var30) {
                throw new CannotGetJdbcConnectionException("Could not Get Jdbc Connection!", var30);
            }

            try {
                t = callback.doInSqlMapClient(session);
            } catch (SQLException var27) {
                t = var27;
                throw (new SQLErrorCodeSQLExceptionTranslator()).translate("SqlMapClient operation", (String) null, var27);
            } catch (Throwable var28) {
                t = var28;
                throw new UnknownDataAccessException("Unknown exception occurs on processing data access!", var28);
            } finally {
                try {
                    if (springCon != null) {
                        if (isTransactionAware) {
                            springCon.close();
                        } else {
                            DataSourceUtils.releaseConnection(springCon, dataSource);
                        }
                    }
                } catch (Throwable var26) {
                    var26.printStackTrace();
                }

            }
        } finally {
            session.close();
        }

        return (T) t;
    }

    DataSource getRealDataSource(DataSource dataSource) {
        if (dataSource instanceof TransactionAwareDataSourceProxy) {
            dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource();
        }

        if (dataSource instanceof MasterSlaveDataSource) {
            dataSource = ((MasterSlaveDataSource) dataSource).selectDataSource();
        }

        return dataSource;
    }
}